package com.stwitinc.redmine.res.news;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.stwitinc.DateFormat;
import com.stwitinc.Util;
import com.stwitinc.aliyun.OSS;
import com.stwitinc.data.model.stwnews.News;
import com.stwitinc.redmine.dao.DAO;
import com.stwitinc.redmine.dao.news.NewsDAOImpl;
import com.stwitinc.redmine.res.sys.SysRes;
import com.stwitinc.servlet.rest.RESTResource;
import com.stwitinc.servlet.rest.ResourceMethod;
import com.stwitinc.servlet.rest.ReturnType;
import com.stwitinc.util.IDGenerator;

public class NewsRes extends RESTResource
{
	@ResourceMethod(returnType = ReturnType.JSON, validateToken = true)
	public JSONObject delete(String newsId) throws Exception {
		DAO.newNewsDAO().deleteNews(Long.parseLong(newsId), getToken().getLongValue("userId"));
		JSONObject result = new JSONObject();
		result.put("error", 0);
		return result;
	}

	@ResourceMethod(returnType = ReturnType.FORWARD, validateToken = false)
	public String get(String newsId) throws Exception {
		JSONObject data = DAO.newNewsDAO().getPublishedNewsById(Long.parseLong(newsId));
		data.put("content", processImages(data.getString("content")));
		setAttribute("data", data);
		return "desktop/news/news.jsp";
	}

	@ResourceMethod(returnType = ReturnType.FORWARD, validateToken = true)
	public String getNewsEditor() {
		setAttribute("isNew", true);
		setAttribute("newsId", IDGenerator.generateSNString());
		return "desktop/news/news-editor.jsp";
	}

	@ResourceMethod(returnType = ReturnType.FORWARD, validateToken = true)
	public String getNewsEditor(String newsId) throws Exception {
		setAttribute("isNew", false);
		setAttribute("newsId", newsId);
		JSONObject rec = new NewsDAOImpl().getNewsById(Long.parseLong(newsId));
		String titleImageUri = rec.getString("titleImageUri");
		if (!Util.isNullOrWhiteSpace(titleImageUri)) {
			rec.put("presignedTitleImageUri", OSS.generatePresignedURL(SysRes.MODULE_NAME, titleImageUri));
		}
		setAttribute("rec", rec);
		return "desktop/news/news-editor.jsp";
	}

	@ResourceMethod(returnType = ReturnType.JSON, validateToken = true)
	public JSONObject getNewsList() throws Exception {
		String pageIndexStr = getParameter("pageIndex");
		int pageIndex = pageIndexStr == null ? 0 : Integer.parseInt(pageIndexStr);
		String categoryStr = getParameter("category");
		Integer category = categoryStr == null ? null : Integer.parseInt(categoryStr);
		try {
			JSONObject data = DAO.newNewsDAO().getPublishedNewsList(pageIndex, category);
			JSONArray array = data.getJSONArray("records");
			String[] keys = new String[array.size()];
			for (int i = 0; i < array.size(); i++) {
				JSONObject rec = array.getJSONObject(i);
				long newsId = rec.getLongValue("newsId");
				String newsUri = "news/news/" + newsId;
				rec.remove("newsId");
				rec.put("newsUri", newsUri);
				keys[i] = rec.getString("titleImageUri");
				// 格式化输出日期
				rec.put("createTime", DateFormat.DATE_TIME_WITHOUT_SECONDS.formatDate(rec.getDate("createTime")));
				rec.put("modifyTime", DateFormat.DATE_TIME_WITHOUT_SECONDS.formatDate(rec.getDate("modifyTime")));
				rec.put("publishTime", DateFormat.DATE_TIME_WITHOUT_SECONDS.formatDate(rec.getDate("publishTime")));
			}
			String[] urls = OSS.generatePresignedURLs(SysRes.MODULE_NAME, keys);
			for (int i = 0; i < array.size(); i++) {
				JSONObject rec = array.getJSONObject(i);
				rec.put("ossPresignedTitleImageURL", urls[i]);
			}
			return data;
		} catch (Exception e) {
			JSONObject data = new JSONObject();
			data.put("error", -1);
			data.put("message", e.getMessage());
			return data;
		}
	}

	@ResourceMethod(returnType = ReturnType.FORWARD, validateToken = true)
	public String getNewsManagement() throws Exception {
		String stateStr = getParameter("state");
		int state = stateStr == null ? 1 : Integer.parseInt(stateStr);
		setAttribute("state", state);
		String pageIndexStr = getParameter("pageIndex");
		int pageIndex = pageIndexStr == null ? 0 : Integer.parseInt(pageIndexStr);
		JSONObject data = DAO.newNewsDAO().getNewsList(state, pageIndex);
		JSONArray records = data.getJSONArray("records");
		String[] keys = new String[records.size()];
		for (int i = 0; i < records.size(); i++) {
			JSONObject rec = records.getJSONObject(i);
			keys[i] = rec.getString("titleImageUri");
			// 格式化输出日期
			rec.put("createTime", DateFormat.DATE_TIME_WITHOUT_SECONDS.formatDate(rec.getDate("createTime")));
			rec.put("modifyTime", DateFormat.DATE_TIME_WITHOUT_SECONDS.formatDate(rec.getDate("modifyTime")));
			rec.put("publishTime", DateFormat.DATE_TIME_WITHOUT_SECONDS.formatDate(rec.getDate("publishTime")));
		}
		String[] urls = OSS.generatePresignedURLs(SysRes.MODULE_NAME, keys);
		for (int i = 0; i < records.size(); i++) {
			JSONObject rec = records.getJSONObject(i);
			rec.put("ossPresignedTitleImageURL", urls[i]);
		}
		setAttribute("data", data);
		return "desktop/news/news-management.jsp";
	}

	@ResourceMethod(returnType = ReturnType.FORWARD, validateToken = true)
	public String getPreview(String newsId) throws Exception {
		JSONObject data = DAO.newNewsDAO().getNewsById(Long.parseLong(newsId));
		data.put("content", processImages(data.getString("content")));
		data.put("publishDate", DateFormat.DATE.formatDate(data.getDate("publishTime")));
		setAttribute("data", data);
		return "desktop/news/news.jsp";
	}

	@ResourceMethod(returnType = ReturnType.REDIRECT, validateToken = true)
	public String post(String newsId) throws Exception {
		News rec = new News();
		rec.read(this);
		rec.setNewsId(newsId);
		if (Boolean.parseBoolean(getParameter("isNew"))) {
			DAO.newNewsDAO().addNews(rec, getToken().getLongValue("userId"));
			return "news/news/news_management?tokenId=" + getToken().getString("tokenId");
		} else {
			int state = Integer.parseInt(getParameter("state"));
			DAO.newNewsDAO().modifyNews(rec, getToken().getLongValue("userId"));
			return "news/news/news_management?tokenId=" + getToken().getString("tokenId") + "&state=" + state;
		}
	}

	@ResourceMethod(returnType = ReturnType.JSON, validateToken = true)
	public JSONObject putPublish(String newsId) throws Exception {
		DAO.newNewsDAO().publishNews(Long.parseLong(newsId), getToken().getLongValue("userId"));
		JSONObject result = new JSONObject();
		result.put("error", 0);
		return result;
	}

	private String processImages(String content) throws Exception {
		if (content == null) {
			return null;
		}
		Pattern p = Pattern.compile("(?<=<img src=\")[^\"]+(?=\")");
		Matcher m = p.matcher(content);
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			String key = m.group();
			if (key.startsWith("http")) {
				continue;
			}
			String url = OSS.generatePresignedURL(SysRes.MODULE_NAME, key);
			m.appendReplacement(sb, url);
		}
		m.appendTail(sb);
		return sb.toString();
	}
}
